import { Table, Input, Divider, Tooltip, InputNumber, Select, Grid } from 'antd';
import React, { useState, useMemo, useEffect, useRef } from 'react';
import AutoTable from '@/components/AutoTable/mtable';
import { Scrollbars } from 'react-custom-scrollbars';
import { CloseOutlined } from '@ant-design/icons';
import styles from './index.less';

let { Option } = Select;
const { useBreakpoint } = Grid;

function unique(arr, key) {
  var hash = [];
  for (var i = 0; i < arr.length; i++) {
    let hashlist = hash.length > 0 ? hash.map((it) => it[key]) : [];
    if (arr[i] && hashlist.indexOf(arr[i][key]) == -1) {
      hash.push(arr[i]);
    }
  }
  return hash;
}

const usePrevious = (value) => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};

export default function CheckTable({
  value,
  onChange,
  pagination,
  columns,
  extraparams,
  path,
  editable,
  rowKey,
  rowName,
  tabletype = 'checkbox',
  dataSource,
}) {
  let [first, cf] = useState(true),
    [currentkey, changecur] = useState(),
    newcolumns = columns,
    [expandedRows, cexpand] = useState([]),
    [options, setoptions] = useState({});
  const preParams = usePrevious(extraparams);
  const screens = useBreakpoint();

  if (editable) {
    function getval(item, record) {
      let { dataIndex } = item, //修改字段的key
        hasval =
          value && value.length > 0 ? value.filter((it) => it[rowKey] == record[rowKey]) : []; //value中是否存在id为当前的值
      if (hasval.length == 0) {
        //不存在
        return record[dataIndex];
      } else {
        //存在
        return hasval[0][dataIndex];
      }
    }
    newcolumns = columns.map((item, i) => {
      let idlist = value ? value.map((it) => it[rowKey]) : [];
      //下拉options定义
      //编辑逻辑
      if (item.selectedRender == 'InputNumber') {
        let render = (_, record) => {
          if (idlist.indexOf(record[rowKey]) == -1) {
            return <span>{getval(item, record)}</span>;
          } else {
            return (
              <InputNumber
                value={getval(item, record)}
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              />
            );
          }
        };
        item.render = render;
      } else if (item.selectedRender == 'Select') {
        let render = (_, record) => {
          let curselected = Array.isArray(record[item.dataIndex])
            ? record[item.dataIndex]
            : record[item.dataIndex]
            ? [record[item.dataIndex]]
            : [];
          let alloption = unique([...options[item.key], ...curselected], 'value');
          let resval = getval(item, record);
          if (item.mode == 'multiple') {
            return (
              <Select
                disabled={idlist.indexOf(record[rowKey]) == -1}
                mode={item.mode}
                value={resval ? resval.map((it) => (it?.value ? it.value : it)) : []}
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              >
                {Array.isArray(item.options)
                  ? item.options.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))
                  : alloption.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))}
              </Select>
            );
          } else {
            return (
              <Select
                disabled={idlist.indexOf(record[rowKey]) == -1}
                mode={item.mode}
                value={
                  resval
                    ? Array.isArray(resval)
                      ? resval.map((it) => (it?.value ? it.value : it))[0]
                      : resval
                    : null
                }
                onChange={(val) => {
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              >
                {Array.isArray(item.options)
                  ? item.options.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))
                  : alloption.map((it, i) => (
                      <Option key={i} value={it.value}>
                        {it.label}
                      </Option>
                    ))}
              </Select>
            );
          }
        };
        item.render = render;
      } else if (item.selectedRender == 'Input') {
        let render = (_, record) => {
          if (idlist.indexOf(record[rowKey]) == -1) {
            return <span>{getval(item, record)}</span>;
          } else {
            return (
              <Input
                value={getval(item, record)}
                onChange={(e) => {
                  let val = e.target.value;
                  let newvalue = value.map((it) => {
                    if (it[rowKey] == record[rowKey]) {
                      it[item.dataIndex] = val;
                    }
                    return it;
                  });
                  onChange(newvalue);
                }}
              />
            );
          }
        };
        item.render = render;
      }
      return item;
    });
  }

  function getoptions(extraparams) {
    columns.map((item) => {
      if (!Array.isArray(item.options) && item.options && item.selectedRender) {
        item.options(item.params ? item.params : { ...extraparams }).then((res) => {
          setoptions({
            ...options,
            [item.key]: res.data.dataList,
          });
        });
      }
    });
  }

  useMemo(() => {
    if (!extraparams || JSON.stringify(preParams) == JSON.stringify(extraparams)) {
      return;
    }
    onChange([]); //传参改变清空数据
    getoptions(extraparams);
  }, [extraparams]);

  return editable ? (
    <div style={{ border: '#ddd solid 1px', overflow: 'auto' }} className="fatable">
      <AutoTable
        showQuickJumper="false"
        rowKey={rowKey}
        dataSource={dataSource}
        columns={newcolumns}
        pagination={pagination}
        extraparams={extraparams}
        getDefaultSelected={(data) => {
          //查询时的初始化
          if (data.selectedList && data.selectedList.length > 0 && first) {
            onChange(
              data.selectedList.map((it) => {
                let cir = it;
                for (let i in it) {
                  if (Array.isArray(it[i])) {
                    let ismu = columns.filter((it) => it.dataIndex == i)[0];
                    if (ismu && ismu.mode == 'multiple') {
                      cir[i] = it[i].map((item) => (item?.value ? item?.value : item));
                    } else {
                      cir[i] = it[i].map((item) => (item?.value ? item?.value : item))[0];
                    }
                  }
                }
                return cir;
              }),
            ); //设置value
            cf(false);
          }
        }}
        path={path}
        rowSelection={{
          selectedRowKeys: value ? value.map((it) => it[rowKey]) : [],
          preserveSelectedRowKeys: true,
          onChange: (selectedRowKeys, expandedRowes) => {
            let conval = value && Array.isArray(value) ? value : [];
            let limits = unique([...conval, ...expandedRowes], rowKey),
              expander = [];
            expander = selectedRowKeys.map((it) => {
              return limits.filter((item) => item[rowKey] == it)[0];
            });
            expander = expander.map((it) => {
              let neit = it;
              Object.keys(options).map((item) => {
                let vals = neit[item];
                if (vals) {
                  if (Array.isArray(vals)) {
                    vals = vals.map((it) => (it?.value ? it.value : it));
                  }
                }
                neit = {
                  ...neit,
                  [item]: vals,
                };
              });
              return neit;
            });
            onChange(expander);
          },
        }}
        tableRender={(_, dom) => (
          <div
            style={{
              display: 'flex',
              width: '100%',
            }}
          >
            <div
              style={{
                flex: 1,
              }}
            >
              {dom}
            </div>
            {value?.length > 0 && Object.values(screens).filter((it) => it === true).length > 2 && (
              <div
                style={{
                  width: 120,
                  overflow: 'hidden',
                  display: 'flex',
                  flexDirection: 'column',
                  backgroundColor: '#ffffff',
                }}
              >
                <div
                  style={{
                    padding: '14px 6px',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                  }}
                >
                  <span style={{ fontSize: 16 }}>选中：</span>
                  <span style={{ fontSize: 16 }}>{value?.length}个</span>
                </div>
                <div style={{ flex: 1, paddingBottom: 18 }}>
                  <Scrollbars
                    thumbMinSize={10}
                    autoHide
                    style={{ width: '100%', height: '100%' }}
                    hideTracksWhenNotNeeded={true}
                  >
                    {value.map((it, i) => {
                      return (
                        <div
                          key={i}
                          className={styles.items}
                          onClick={() => {
                            changecur(it[rowKey]);
                          }}
                        >
                          <Tooltip title={it[rowName] ? it[rowName] : ''}>
                            <i>{it[rowName] ? it[rowName] : ''}</i>
                          </Tooltip>

                          <CloseOutlined
                            onClick={(e) => {
                              e.stopPropagation();
                              if (it[rowKey] == currentkey) {
                                changecur(null);
                              }
                              let newexpandedRows = value.filter(
                                (its) => its[rowKey] != it[rowKey],
                              );
                              onChange(newexpandedRows);
                            }}
                          />
                        </div>
                      );
                    })}
                  </Scrollbars>
                </div>
              </div>
            )}
          </div>
        )}
        rowClassNameFn={(record, index) => {
          if (currentkey === record[rowKey]) {
            return 'selectedRow';
          }
          return null;
        }}
      />
    </div>
  ) : (
    <div style={{ border: '#ddd solid 1px', overflow: 'auto' }} className="fatable">
      <AutoTable
        showQuickJumper="false"
        rowKey={rowKey}
        columns={columns}
        dataSource={dataSource}
        pagination={pagination}
        extraparams={extraparams}
        getDefaultSelected={(data) => {
          if (value && first) {
            cexpand([...expandedRows, ...value]);
            cf(false);
          }
        }}
        path={path}
        rowSelection={{
          selectedRowKeys: value
            ? value.map((it) => {
                if (typeof it == 'object') {
                  return it[rowKey];
                } else {
                  return it;
                }
              })
            : [],
          preserveSelectedRowKeys: true,
          type: tabletype,
          onChange: (selectedRowKeys, expandedRowes) => {
            onChange(selectedRowKeys);
            let limits = unique([...expandedRows, ...expandedRowes], rowKey),
              expander = [];
            expander = selectedRowKeys.map((it) => {
              return limits.filter((item) => item[rowKey] == it)[0];
            });
            cexpand(expander);
          },
        }}
        tableRender={(_, dom) => (
          <div
            style={{
              display: 'flex',
              width: '100%',
            }}
          >
            <div
              style={{
                flex: 1,
              }}
            >
              {dom}
            </div>
            {value?.length > 0 && Object.values(screens).filter((it) => it === true).length > 2 && (
              <div
                style={{
                  width: 120,
                  overflow: 'hidden',
                  display: 'flex',
                  flexDirection: 'column',
                  backgroundColor: '#ffffff',
                }}
              >
                <div
                  style={{
                    padding: '14px 6px',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                  }}
                >
                  <span style={{ fontSize: 16 }}>选中：</span>
                  <span style={{ fontSize: 16 }}>{value?.length}个</span>
                </div>
                <div style={{ flex: 1, paddingBottom: 18 }}>
                  <Scrollbars
                    thumbMinSize={10}
                    autoHide
                    style={{ width: '100%', height: '100%' }}
                    hideTracksWhenNotNeeded={true}
                  >
                    {expandedRows.map((it) => {
                      return (
                        <div
                          className={styles.items}
                          onClick={() => {
                            changecur(it[rowKey]);
                          }}
                        >
                          <Tooltip title={it ? it[rowName] : ''}>
                            <i>{it ? it[rowName] : ''}</i>
                          </Tooltip>

                          <CloseOutlined
                            onClick={(e) => {
                              e.stopPropagation();
                              if (it[rowKey] == currentkey) {
                                changecur(null);
                              }
                              let newvalues = value.filter((item) => item != it[rowKey]);
                              onChange(newvalues);
                              let newexpandedRows = expandedRows.filter(
                                (its) => its[rowKey] != it[rowKey],
                              );
                              cexpand(newexpandedRows);
                            }}
                          />
                        </div>
                      );
                    })}
                  </Scrollbars>
                </div>
              </div>
            )}
          </div>
        )}
        rowClassNameFn={(record, index) => {
          if (currentkey === record[rowKey]) {
            return 'selectedRow';
          }
          return null;
        }}
      />
    </div>
  );
}
